package net.oschina.arvin.sqlbuilder.definition;

import net.oschina.arvin.sqlbuilder.WhereBuilder;
import net.oschina.arvin.sqlbuilder.enums.CompareType;
import net.oschina.arvin.sqlbuilder.utils.AssertUtil;

import java.lang.reflect.Field;

/**
 * 查询条件项
 *
 * @author Arvin
 * @time 2017/11/17 13:40
 */
public abstract class AbstractConditionItem<T extends QueryConditionColumnDefinition> implements ConditionItem {

    /** 对应模型列定义 */
    private final ColumnDefinition modelColumnDefinition;

    /** 对应查询条件列定义 */
    private final T queryConditionColumnDefinition;

    public AbstractConditionItem(ColumnDefinition modelColumnDefinition, T queryConditionColumnDefinition) {

        AssertUtil.assertNotNull(modelColumnDefinition, "模型列定义不能为空！");
        AssertUtil.assertNotNull(queryConditionColumnDefinition, "查询条件列定义不能为空！");

        AssertUtil.assertTrue(modelColumnDefinition.getFieldName().equals(queryConditionColumnDefinition.getQueryFieldName()),
                "模型列和查询条件列的名称应该一致");

        this.modelColumnDefinition = modelColumnDefinition;
        this.queryConditionColumnDefinition = queryConditionColumnDefinition;
    }

    public T getQueryConditionColumnDefinition() {
        return queryConditionColumnDefinition;
    }

    public ColumnDefinition getModelColumnDefinition() {
        return modelColumnDefinition;
    }

    @Override
    public Field getQueryConditionField() {
        return getModelColumnDefinition().getField();
    }


    /**
     * 返回是否进行了追加
     *
     * @param whereBuilder Where子句构造器
     * @return 返回是否进行了追加
     */
    @Override
    public boolean appendToWhereBuilder(Object queryCondition, WhereBuilder whereBuilder, CompareType compareType) {
        AssertUtil.assertNotNull(whereBuilder, "WhereBuilder 不能为空！");

        compareType = null == compareType ? getQueryConditionColumnDefinition().getCompareType() : compareType;

        AssertUtil.assertTrue(null != compareType && isSupportCompareType(compareType), getFieldStringInfo() + " 不支持比较类型 [" + compareType + "]！");

        return customAppendToWhereBuilder(queryCondition, whereBuilder, compareType);
    }

    /**
     * 属性信息
     *
     * @return
     */
    protected abstract String getFieldStringInfo();

    /**
     * 验证是否是支持的查询类型
     *
     * @param compareType 要验证的查询类型
     */
    protected abstract boolean isSupportCompareType(CompareType compareType);

    /**
     * 自定义 append 策略
     */
    protected abstract boolean customAppendToWhereBuilder(Object queryCondition, WhereBuilder whereBuilder, CompareType compareType);

}
